package com.wsjzzcbq.qianyuan.sys.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsjzzcbq.qianyuan.common.bean.PageBean;
import com.wsjzzcbq.qianyuan.common.bean.R;
import com.wsjzzcbq.qianyuan.common.constant.MsgConsts;
import com.wsjzzcbq.qianyuan.sys.bean.SysRole;
import com.wsjzzcbq.qianyuan.sys.bean.SysRolePermission;
import com.wsjzzcbq.qianyuan.sys.mapper.SysRoleMapper;
import com.wsjzzcbq.qianyuan.sys.param.AddSysRoleParam;
import com.wsjzzcbq.qianyuan.sys.param.FindSysRoleListParam;
import com.wsjzzcbq.qianyuan.sys.service.MenuService;
import com.wsjzzcbq.qianyuan.sys.service.SysRolePermissionService;
import com.wsjzzcbq.qianyuan.sys.service.SysRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * RoleServiceImpl
 *
 * @author wsjz
 * @date 2022/03/11
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private MenuService menuService;

    @Autowired
    private SysRolePermissionService rolePermissionService;

    @Override
    public R<PageBean<SysRole>> findList(FindSysRoleListParam param) {
        QueryWrapper<SysRole> lqw = new QueryWrapper<>();
        if (StringUtils.isNotBlank(param.getName())) {
            lqw.like("name", param.getName());
        }
        if (param.getCreateDate() != null && !param.getCreateDate().isEmpty()) {
            lqw.between("DATE_FORMAT(create_date,'%Y-%m-%d')", param.getCreateDate().get(0), param.getCreateDate().get(1));
        }
        lqw.orderByDesc("create_date");
        IPage<SysRole> iPage = this.page(new Page<>(param.getPageNum(), param.getPageSize()), lqw);
        PageBean<SysRole> pageBean = PageBean.create(iPage);

        return R.success(pageBean);
    }

    @Override
    public R<?> findAllMenuList() {
        return R.success(menuService.menuPermission());
    }

    @Transactional
    @Override
    public R<?> addOrUpdateSysRole(AddSysRoleParam param) {
        SysRole role = new SysRole();
        role.setName(param.getName());

        List<String> menuIds = param.getMenuIds();

        if (StringUtils.isBlank(param.getId())) {
            //添加
            this.save(role);

            if (menuIds != null && !menuIds.isEmpty()) {
                addPermissionRelationRole(menuIds, role.getId());
            }
            return R.success(MsgConsts.ADD_SUCCESS);
        } else {
            //修改
            SysRole sysRole = this.getById(param.getId());
            if (sysRole != null) {
                role.setId(Long.valueOf(param.getId()));
                this.updateById(role);
                //先删除角色原权限
                LambdaQueryWrapper<SysRolePermission> lqw = new LambdaQueryWrapper<>();
                lqw.eq(SysRolePermission::getRoleId, role.getId());
                rolePermissionService.remove(lqw);
                if (menuIds != null && !menuIds.isEmpty()) {
                    addPermissionRelationRole(menuIds, role.getId());
                }
            }
            return R.success(MsgConsts.UPDATE_SUCCESS);
        }
    }

    /**
     * 添加角色权限关联数据
     * @param menuIds
     * @param roleId
     */
    private void addPermissionRelationRole(List<String> menuIds, Long roleId) {
        List<SysRolePermission> rolePermissions = new LinkedList<>();
        menuIds.forEach(v->{
            SysRolePermission permission = new SysRolePermission();
            permission.setMenuId(Long.valueOf(v));
            permission.setRoleId(roleId);
            rolePermissions.add(permission);
        });
        rolePermissionService.saveBatch(rolePermissions);
    }

    @Override
    public R<?> findSysRoleById(String id) {
        if (StringUtils.isBlank(id)) {
            return R.error(MsgConsts.ID_NOT_NULL);
        }
        SysRole sysRole = this.getById(id);

        LambdaQueryWrapper<SysRolePermission> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SysRolePermission::getRoleId, id);
        lqw.select(SysRolePermission::getMenuId);
        List<String> list = rolePermissionService.list(lqw).stream()
                .map(v->String.valueOf(v.getMenuId()))
                .collect(Collectors.toList());

        JSONObject role = new JSONObject();
        role.put("id", id);
        role.put("name", sysRole.getName());
        role.put("menuIds", list);

        JSONArray treeData = menuService.menuPermission();

        JSONObject result = new JSONObject();
        result.put("role", role);
        result.put("treeData", treeData);
        return R.success(result);
    }

    @Transactional
    @Override
    public R<?> deleteSysRoleById(String id) {
        if (StringUtils.isBlank(id)) {
            return R.error(MsgConsts.ID_NOT_NULL);
        }
        SysRole sysRole =  this.getById(id);
        if (sysRole == null) {
            return R.error(MsgConsts.ID_ERROR);
        }

        LambdaQueryWrapper<SysRolePermission> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SysRolePermission::getRoleId, id);
        rolePermissionService.remove(lqw);
        this.removeById(id);
        return R.success(MsgConsts.DELETE_SUCCESS);
    }

    @Override
    public R<?> findRoles() {
        return R.success(this.list());
    }
}
